package com.uyun.rbac.shiro;

import com.uyun.rbac.permission.entity.PermissionEntity;
import com.uyun.rbac.permission.entity.RoleEntity;
import com.uyun.rbac.permission.service.PermissionService;
import com.uyun.util.SpringContextUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import java.util.*;


/**
 * Created by Administrator on 2016/8/4.
 */
@Service(value = "authService")
public class AuthServiceImpl implements IAuthService {

    private static final Logger log = LoggerFactory.getLogger(AuthServiceImpl.class);


    @Autowired
    private PermissionService permissionService;


    //注意/r/n前不能有空格
    private static final String CRLF = "\r\n";
    private static final String LAST_AUTH_STR = "/** =authc\r\n";


    @Override
    public String loadFilterChainDefinitions() {


        return  getFixedAuthRule() +
                getDynaAuthRule() +
                LAST_AUTH_STR;
     }


    /**
     * 重新加载数据库权限
     *
     */
    public synchronized void reCreateFilterChains(ShiroFilterFactoryBean shiroFilterFactoryBean) {

        AbstractShiroFilter shiroFilter ;
        PathMatchingFilterChainResolver filterChainResolver ;
        DefaultFilterChainManager manager ;

/*        ApplicationContext ctx = SpringContextUtils.getApplicationContext();

        String[] beanNames = ctx.getBeanDefinitionNames();


        ShiroFilterFactoryBean shiroFilterFactoryBean = (ShiroFilterFactoryBean) SpringContextUtils.getBeanById("shiroFilter");
        Object o2 =  SpringContextUtils.getBeanById("securityManager");*/

       // ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        try {
            shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean
                    .getObject();
            filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter
                    .getFilterChainResolver();
            manager = (DefaultFilterChainManager) filterChainResolver
                    .getFilterChainManager();
        } catch (Exception e) {
            log.error("获取shiroFilter出错"+e);
            throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!");
        }

        // 清空老的权限控制
        manager.getFilterChains().clear();

        shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
        shiroFilterFactoryBean
                .setFilterChainDefinitions(loadFilterChainDefinitions());
        // 重新构建生成
        Map<String, String> chains = shiroFilterFactoryBean
                .getFilterChainDefinitionMap();
        for (Map.Entry<String, String> entry : chains.entrySet()) {
            String url = entry.getKey();
            String chainDefinition = entry.getValue().trim().replace(" ", "");
            manager.createChain(url, chainDefinition);
        }
    }



    //根据角色，得到动态权限规则
    private String getDynaAuthRule() {

        StringBuilder sb = new StringBuilder();

        List<RoleEntity> allRoleEntities = permissionService.getAllRoleEntity();

        Map<Integer,PermissionEntity> allPermissionList = new HashMap<>();

        for(RoleEntity roleEntity:allRoleEntities){

            List<PermissionEntity> permissionEntityList = roleEntity.getPermissionEntityList();

            if(permissionEntityList!=null&&!permissionEntityList.isEmpty()){
                permissionEntityList.stream().forEach(permissionEntity ->allPermissionList.put(permissionEntity.getId(),permissionEntity) );
            }

        }

        List<Map.Entry<Integer, PermissionEntity>> list = new ArrayList<>(allPermissionList.entrySet());
        for (Map.Entry<Integer, PermissionEntity> entity : list) {

            PermissionEntity permissionEntity = entity.getValue();
            sb.append(permissionEntity.getUrl()).append("=perms[").append(permissionEntity.getMapping()).append("]"+CRLF);

        }



        return sb.toString();
    }


    //得到固定权限验证规则串
    private String getFixedAuthRule() {


        return  " /css/**  = anon " + CRLF +
                " /dist/**  = anon " + CRLF +
                " /fonts/**  = anon " + CRLF +
                " /images/**  = anon " + CRLF +
                " /js/**  = anon " + CRLF +
                " /plugins/**  = anon " + CRLF +
                " /login.htm  = anon " + CRLF +
                " /logon  = anon " + CRLF +
                " /signOut.htm  = anon " + CRLF +
                " /captcha  = anon " + CRLF;

    }


}